if BUILDOPT_SYSTEMD
systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \
src/boot/ostree-remount.service \
- src/boot/ostree-shutdown.service \
src/boot/ostree-boot-complete.service \
src/boot/ostree-finalize-staged.service \
src/boot/ostree-finalize-staged-hold.service \
src/boot/ostree-boot-complete.service \
src/boot/ostree-prepare-root.service \
src/boot/ostree-remount.service \
- src/boot/ostree-shutdown.service \
src/boot/ostree-finalize-staged.service \
src/boot/ostree-finalize-staged-hold.service \
src/boot/ostree-state-overlay@.service \
+++ /dev/null
-# SPDX-License-Identifier: LGPL-2.0+
-
-[Unit]
-Description=OSTree Shutdown
-Documentation=man:ostree(1)
-DefaultDependencies=no
-# Only enabled via generator, but for good measure
-ConditionKernelCommandLine=ostree
-# Run after core mounts
-RequiresMountsFor=/etc /sysroot
-# However, we want to only shut down after `/var` has been umounted.
-# Since this runs via ExecStop, this Before= is actually After= at shutdown
-Before=var.mount
-Conflicts=umount.target
-Before=umount.target
-
-[Service]
-Type=oneshot
-RemainAfterExit=yes
-ExecStop=/usr/lib/ostree/ostree-remount --shutdown
-
-# No [Install] section - we're only enabled via generator
#include "ostree-mount-util.h"
#include "otcore.h"
-static gboolean opt_shutdown;
-
-static GOptionEntry options[] = { { "shutdown", 'S', 0, G_OPTION_ARG_NONE, &opt_shutdown,
- "Perform shutdown unmounting", NULL },
- { NULL } };
-
static void
do_remount (const char *target, bool writable)
{
#endif
}
-// ostree-prepare-root sets things up so that /sysroot points to the "physical" (real) root in the
-// initramfs, and then with composefs `/` is an overlay+EROFS that holds references to content in
-// that physical filesystem.
-//
-// In a typical mutable system where the OS is in a mutable `/` (or `/usr), systemd explicitly
-// skips unmounting both `/` and `/usr`. It will remount them read-only though - and that's
-// the semantic we want to match here.
-static void
-do_shutdown (void)
-{
- const char *sysroot = "/sysroot";
- if (mount (sysroot, sysroot, NULL, MS_REMOUNT | MS_SILENT | MS_RDONLY, NULL) < 0)
- {
- // Hopefully at this point nothing has any write references, but if they
- // do we still want to continue.
- perror ("Remounting /sysroot read-only");
- }
- // And fully detach it from the mountns because otherwise systemd thinks
- // it can be unmounted, but it can't - it's required by `/` (and in a
- // composefs setup `/etc`) and possibly `/var`. Again, we only really
- // care that it got mounted read-only and hence outstanding data flushed.
- // A better fix in the future would be to teach systemd to honor `-.mount`
- // having a `Requires=sysroot.mount` meaning we can't unmount the latter.
- if (umount2 (sysroot, MNT_DETACH) < 0)
- err (EXIT_FAILURE, "umount(/sysroot)");
-
- // And finally: /etc
- // NOTE! This one is intentionally last in that we want to try to make
- // this read-only, but if it fails, systemd-shutdown will have another
- // attempt after a process killing spree. If anything happens to be
- // holding a writable fd at this point, conceptually it would have
- // created race conditions vs ostree-finalize-staged.service, and so
- // having this service fail will be a signal that those things need
- // to be fixed.
- do_remount ("/etc", false);
- // Don't add anything else after this.
-}
-
int
main (int argc, char *argv[])
{
g_autoptr (GError) error = NULL;
- g_autoptr (GOptionContext) context = g_option_context_new ("");
- g_option_context_add_main_entries (context, options, NULL);
- if (!g_option_context_parse (context, &argc, &argv, &error))
- errx (EXIT_FAILURE, "Error parsing options: %s", error->message);
-
- // Handle the shutdown option
- if (opt_shutdown)
- {
- do_shutdown ();
- return 0;
- }
- // Otherwise fall through to the default startup
-
g_autoptr (GVariant) ostree_run_metadata_v = NULL;
{
glnx_autofd int fd = open (OTCORE_RUN_BOOTED, O_RDONLY | O_CLOEXEC);